package com.example.petcare.controller.provider;

import com.example.petcare.pojo.Provider;
import com.example.petcare.pojo.Result;
import com.example.petcare.service.ProviderService;
import com.example.petcare.utils.JwtUtil;
import com.example.petcare.utils.Md5Util;
import com.example.petcare.utils.ThreadLocalUtil;
import jakarta.validation.constraints.Pattern;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController//标记为控制器类,并且返回json数据
@RequestMapping("/provider")//请求路径
@Slf4j
public class ProviderController {

    @Autowired
    private ProviderService providerService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;// 注入redis模板


    // 注册
    @PostMapping("/register")
    public Result register(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password) {
        // 查询数据库是否存在该商家
        Provider p = providerService.findByUsername(username);

        if (p == null) {
            // 没有占用,可以注册
            providerService.register(username, password);
            return Result.success();
        } else {
            // 已经存在该商家,不可以注册
            return Result.error("用户名已被占用");
        }
        // 查出来没有该商家,可以注册
    }


    // 登录
    @PostMapping("/login")
    public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password) {
        // 根据用户名查询用户
        Provider loginProvider = providerService.findByUsername(username);

        // 判断该用户是否存在
        if (loginProvider == null) {
            return Result.error("用户名不存在");
        }

        // 判断providerId是否为0,如果为0,说明是admin,admin不能用商家端口登录
//        if (loginProvider.getProviderId() == 0){
//            return Result.error("平台管理员不能在商家端口登录");
//        }


        // 判断密码是否正确     loginuser对象中的密码是密文
        if (Md5Util.getMD5String(password).equals(loginProvider.getPassword())) {

            // 登录成功,生成jwt token令牌
            Map<String,Object> claims = new HashMap<>();// 创建一个map集合
            claims.put("ProviderId",loginProvider.getProviderId());// 将用户id和用户名放入map集合
            claims.put("username",loginProvider.getUsername());

            // 输出claims中的内容
            log.info("这是ProviderController中的claims:{}",claims);


            String role = "provider";// 角色
            // 把role存入ThreadLocal
            ThreadLocalUtil.setRole(role);
            log.info("这是ProviderController中的role:{}",ThreadLocalUtil.getRole());

            String token = JwtUtil.genToken(claims,role);// 生成jwt token令牌

            // 把token存储到redis中
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            operations.set(token,token,365, TimeUnit.DAYS);// 把token既作为键，又作为值存进去

            return Result.success(token);// 返回token


        }

        return Result.error("密码错误");
    }

    // 获取用户信息
    @GetMapping("/providerInfo")
    public Result<Provider> userInfo() {


        Map<String,Object> map = ThreadLocalUtil.get();// 从ThreadLocal中获取数据
        String username = (String) map.get("username");// 获取用户名

        Provider provider = providerService.findByUsername(username);// 根据用户名查询用户,返回用户对象
        return Result.success(provider);// 返回用户对象

    }

    // 更新用户信息
    @PutMapping("/update")
    public Result update(@RequestBody @Validated Provider provider){
        providerService.update(provider);// 更新用户信息
        return Result.success();// 返回成功
    }

    // 更新密码
    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody Map<String,String> params, @RequestHeader("Authorization") String token){

        // @RequestHeader("Authorization")  String token
        // token是浏览器通过请求头的方式携带过来的,请求头的名字叫Authorization

        // 1.校验参数
        String oldPwd = params.get("old_pwd");// 获取旧密码
        String newPwd = params.get("new_pwd");// 获取新密码
        String rePwd = params.get("re_pwd");// 获取确认密码

        if(!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)){
            return Result.error("缺少必要的参数");
        }

        // 新密码不能和旧密码一样
        if (oldPwd.equals(newPwd)){
            return Result.error("新密码不能和旧密码一样");
        }

        // 原密码是否正确
        // 调用providerService根据用户名拿到原密码，再和old_Pwd比对
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        Provider loginProvider= providerService.findByUsername(username);
        if(!loginProvider.getPassword().equals(Md5Util.getMD5String(oldPwd))){
            return Result.error("原密码错误");
        }

        // 新密码和确认密码是否一致,即newPwd和rePwd是否相等
        if (!newPwd.equals(rePwd)){
            return Result.error("两次填写的新密码不一致");
        }

        // 2.调用service完成密码更新
        providerService.updatePwd(newPwd);
        System.out.println("新密码是"+newPwd);

        // 删除redis中对应的token
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);

        return Result.success();

    }


}
